package com.zcxy360.sandtable.service;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zcxy360.sandtable.domain.Course;
import com.zcxy360.sandtable.domain.CourseExample;
import com.zcxy360.sandtable.domain.CourseExample.Criteria;
import com.zcxy360.sandtable.domain.CourseMapper;
import com.zcxy360.sandtable.domain.CourseStage;
import com.zcxy360.sandtable.domain.CourseStageMapper;
import com.zcxy360.sandtable.domain.CourseTeamMapper;
import com.zcxy360.sandtable.domain.StageUnit;
import com.zcxy360.sandtable.domain.StageUnitMapper;
import com.zcxy360.sandtable.domain.User;
import com.zcxy360.sandtable.util.ShiroUtil;
import com.zcxy360.sandtable.util.StringUtil;

@Transactional
@Service
public class CourseService {

	@Autowired
	private ObjectMapper objectMapper;
	@Autowired
	private CourseMapper courseMapper;
	@Autowired
	private CourseStageMapper courseStageMapper;
	@Autowired
	private StageUnitMapper stageUnitMapper;
	@Autowired
	private CourseTeamMapper courseTeamMapper;
	@Autowired
	private UserService userService;

	public Course getByCourseId(Integer courseId) {
		Course course = courseMapper.selectByPrimaryKeyWithCascade(courseId);
		if (ShiroUtil.getUser().getRole().equals("student") && course.getType() == 0) {
			throw new RuntimeException("课程未开课,无法进入");
		}
		return course;
	}

	public Object list(Course course, String key, String orderByClause, Integer pageNum, Integer pageSize,
			Integer navigatePages) {
		User loginUser = ShiroUtil.getUser();
		String loginRole = loginUser.getRole();
		if (loginRole.equals("teacher")) {
			course.setUserId(loginUser.getUserId());
		}
		if (loginRole.equals("manager") || loginRole.equals("student")) {
			course.setUserId(null);
			course.setOrgId(loginUser.getOrgId());
		}
		if (loginRole.equals("admin")) {
			course.setUserId(null);
			course.setOrgId(null);
		}
		PageHelper.startPage(pageNum, pageSize);
		List<Course> courses = courseMapper.listWithExtra(course, StringUtil.wrapper(key), orderByClause);
		return new PageInfo<>(courses, navigatePages);
	}

	public Object listForCalendar(Date date, String orderByClause) {
		User loginUser = ShiroUtil.getUser();
		String loginRole = loginUser.getRole();
		Integer userId = null;
		Integer orgId = null;
		if (loginRole.equals("teacher")) {
			userId = loginUser.getUserId();
		}
		if (loginRole.equals("manager")) {
			orgId = loginUser.getOrgId();
		}
		return courseMapper.listForCalendar(userId, orgId, date, orderByClause);
	}

	public Object listForJoin(String key,String orderByClause) {
		return courseMapper.listForJoinWithExtra(ShiroUtil.getUser().getUserId(), StringUtil.wrapper(key),orderByClause);
	}

	public Object listForStudy(Integer type,String orderByClause) {
		return courseMapper.listForStudyWithExtra(ShiroUtil.getUser().getUserId(), type,orderByClause);
	}

	public Object post(Course course, String stageJson, String unitJson, MultipartFile file) {
		Integer completionWeight = course.getCompletionWeight();
		Integer performanceWeight = course.getPerformanceWeight();
		Integer personWeight = course.getPersonWeight();
		Integer teamWeight = course.getTeamWeight();
		if (completionWeight == null || performanceWeight == null || personWeight == null || teamWeight == null) {
			throw new RuntimeException("权重不能为空");
		}
		if (completionWeight + performanceWeight + personWeight + teamWeight != 100) {
			throw new RuntimeException("权重设置错误");
		}
		User loginUser = ShiroUtil.getUser();
		course.setUserId(loginUser.getUserId());
		course.setOrgId(loginUser.getOrgId());
		//创建课程
		courseMapper.insertSelective(course);
		Integer courseId = course.getCourseId();

		JavaType stageJavaType = objectMapper.getTypeFactory().constructParametricType(List.class, CourseStage.class);
		JavaType unitJavaType = objectMapper.getTypeFactory().constructParametricType(List.class, StageUnit.class);
		List<CourseStage> courseStages = null;
		List<StageUnit> stageUnits = null;
		try {
			courseStages = objectMapper.readValue(stageJson, stageJavaType);
			stageUnits = objectMapper.readValue(unitJson, unitJavaType);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("解析数据失败");
		}
		for (CourseStage courseStage : courseStages) {
			courseStage.setCourseId(courseId);
		}
		//创建课程阶段
		courseStageMapper.insertBatch(courseStages);
		int count1 = 1;
		int count2 = 1;
		for (StageUnit stageUnit : stageUnits) {
			Integer type = stageUnit.getType();
			if (type == 1) {
				stageUnit.setStageId(courseStages.get(0).getStageId());
				stageUnit.setSort(count1++);
			}
			if (type == 2) {
				stageUnit.setStageId(courseStages.get(1).getStageId());
				stageUnit.setSort(count2++);
			}
		}
		//创建阶段小节
		stageUnitMapper.create(stageUnits);
		if (file != null) {
			//导入用户
			userService.importUser(file, loginUser.getOrgId(), "student", courseId);
		}
		//创建小组
		courseTeamMapper.create(courseId, course.getTeamCount());
		return course;
	}

	public boolean clone(Course course, MultipartFile file) {
		int courseId = courseMapper.clone(course);
		if (file != null) {
			userService.importUser(file, ShiroUtil.getUser().getOrgId(), "student", courseId);
		}
		return true;
	}

	public boolean update(Course course) {
		Course c = courseMapper.selectByPrimaryKey(course.getCourseId());
		if (c.getType() == 2) {
			throw new RuntimeException("已结束课程禁止修改");
		}
		courseMapper.updateByPrimaryKeySelective(course);
		return true;
	}

	public boolean delete(int[] courseIds) {
		User loginUser = ShiroUtil.getUser();
		String loginRole = loginUser.getRole();
		Course c;
		if (!loginRole.equals("admin")) {
			for (int courseId : courseIds) {
				c = courseMapper.selectByPrimaryKey(courseId);
				if (loginRole.equals("teacher")) {
					if (!c.getUserId().equals(loginUser.getUserId())) {
						throw new RuntimeException("老师只能删除本人的课程");
					}
				}
				if (loginRole.equals("manager")) {
					if (!c.getOrgId().equals(loginUser.getOrgId())) {
						throw new RuntimeException("机构管理员只能删除本机构的课程");
					}
				}
			}
		}
		courseMapper.deleteBatch(courseIds) ;
		return true;
	}

	public boolean checkName(String name) {
		User loginUser = ShiroUtil.getUser();
		CourseExample ex = new CourseExample();
		Criteria or = ex.or();
		or.andNameEqualTo(name);
		if (loginUser.getOrgId() != null) {
			or.andOrgIdEqualTo(loginUser.getOrgId());
		}
		return courseMapper.countByExample(ex) == 0;
	}

	public boolean end(Integer courseId) {
		courseMapper.end(courseId);
		return true;
	}

}
